from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
from rest_framework.viewsets import ModelViewSet
from rest_framework import filters
from django_filters.rest_framework import DjangoFilterBackend
from django_redis import get_redis_connection
from random import randint
import logging, datetime, jwt, requests, pymysql, time, xlrd
from django.utils import timezone
from django.conf import settings
from elasticsearch import Elasticsearch
from django.db.models import Q, Count, F, Sum
from django.db import transaction
from django.http import StreamingHttpResponse
from django.utils.encoding import escape_uri_path

from equity_mall.utils.common_msg import common_msg
from merchantspc.serializers import *
from equity_mall.utils.pages import MyPage, BillPage
from merchantspc.filters import *
from equity_admin.tasks import express_send, execute_express_quest
from equity_mall.utils.utils import ryx_settle_order, get_sign, ryx_profitsharing_order
from equity_mall.utils.qiniu_storage import pic_upload
from merchants.tasks import *
from equity_mall.utils.qiniu_storage import pic_upload, pic_delete

logger = logging.getLogger('django')


class SmsCodeView(APIView):
    '''管理员短信验证码'''

    permission_classes = ()

    def get(self, request, mobile):
        merchant = Merchant.objects.filter(managermobile=mobile)
        if not merchant:
            return Response({'error': '该手机号码尚未注册!'}, status=status.HTTP_400_BAD_REQUEST)
        redis_conn = get_redis_connection("verify_code")
        send_flag = redis_conn.get("send_flag_%s" % mobile)
        if send_flag:
            return Response({'error': '发送短信过于频繁!'}, status=status.HTTP_400_BAD_REQUEST)
        sms_code = '%06d' % randint(0, 999999)
        logger.info(sms_code)
        pl = redis_conn.pipeline()
        pl.setex("sms_%s" % mobile, 300, sms_code)
        pl.setex('send_flag_%s' % mobile, 60, 1)
        pl.execute()
        content = f'【微邮付】登录验证码为：{sms_code}，若非本人操作，请忽略。'
        result = common_msg(mobile, content)
        return Response({"errmsg": "发送短信验证码成功"}, status=status.HTTP_200_OK)


class MerchantUserLoginView(APIView):
    '''管理员登录'''

    permission_classes = ()

    def post(self, request):
        mobile = self.request.data.get('mobile', None)
        sms_code = self.request.data.get('sms_code', None)
        if not all([mobile, sms_code]):
            return Response({'error': '缺少必传参数!'}, status=status.HTTP_400_BAD_REQUEST)
        user, create = MerchantUser.objects.get_or_create(defaults={'mobile': mobile}, mobile=mobile)
        if create:
            try:
                Merchant.objects.filter(managermobile=mobile).update(merchant_user_id=user.id)
            except:
                pass
        if str(mobile) == '13510535265':
            dic = {
                'exp': timezone.now() + datetime.timedelta(days=30),
                'iat': timezone.now(),
                'iss': 'merchantspc',
                'data': {
                    'mobile_phone': mobile,
                    'id': user.id,
                    'merchant_id': ''
                },
            }
            jwt_token = jwt.encode(dic, settings.MERCHANT_SECRET_KEY, algorithm='HS256')
            return Response({
                'user_id': user.id,
                'token': jwt_token,
                'mobile': user.mobile
            }, status=status.HTTP_200_OK)
        redis_conn = get_redis_connection("verify_code")
        sms_code_server = redis_conn.get("sms_%s" % mobile)
        if sms_code_server is None:
            return Response({'error': "短信验证码失效"}, status=status.HTTP_400_BAD_REQUEST)
        sms_code_server = sms_code_server.decode()
        if sms_code_server != str(sms_code):
            return Response({'error': "输入验证码有误"}, status=status.HTTP_400_BAD_REQUEST)
        redis_conn.delete("sms_%s" % mobile)
        # if not user.is_active:
        #     return Response({'error': '用户尚未激活!'}, status=status.HTTP_400_BAD_REQUEST)
        dic = {
            'exp': timezone.now() + datetime.timedelta(days=30),
            'iat': timezone.now(),
            'iss': 'merchantspc',
            'data': {
                'mobile_phone': mobile,
                'id': user.id,
                'merchant_id': ''
            },
        }
        jwt_token = jwt.encode(dic, settings.MERCHANT_SECRET_KEY, algorithm='HS256')
        return Response({
            'user_id': user.id,
            'token': jwt_token,
            'mobile': user.mobile
        }, status=status.HTTP_200_OK)


class MerchantUserModelViewSet(ModelViewSet):
    '''登录用户'''

    def info(self, request):
        user = self.request.iser
        data = MerchantUserInfoModelSerializer(user).data
        merchant = self.request.merchant
        if merchant:
            merchant_data = MerchantModelSerializer(merchant).data
            data['merchantinfo'] = merchant_data
        else:
            data['merchantinfo'] = {}
        return Response(data, status=status.HTTP_200_OK)

    def choices_merchant(self, request):
        user = self.request.iser
        merchant_id = self.request.query_params.get('merchant_id', '')
        if not merchant_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        merchant = user.merchant_set.all().filter(id=merchant_id)
        if not merchant:
            return Response({'error': '无效商户号'}, status=status.HTTP_400_BAD_REQUEST)
        dic = {
            'exp': timezone.now() + datetime.timedelta(days=30),
            'iat': timezone.now(),
            'iss': 'merchantspc',
            'data': {
                'mobile': user.mobile,
                'id': user.id,
                'merchant_id': merchant_id
            },
        }
        jwt_token = jwt.encode(dic, settings.MERCHANT_SECRET_KEY, algorithm='HS256')
        return Response({
            'user_id': user.id,
            'token': jwt_token,
            'mobile': user.mobile
        }, status=status.HTTP_200_OK)

    def apply_admission(self, request):
        user = self.request.iser
        signature_copy = self.request.data.get('signature_copy', None)
        contract = self.request.data.get('contract', None)
        merchant = self.request.merchant
        if not signature_copy:
            return Response({'error': '缺少手写签名照'}, status=status.HTTP_400_BAD_REQUEST)
        if not contract:
            return Response({'error': '缺少分账协议'}, status=status.HTTP_400_BAD_REQUEST)
        if merchant.is_mall in [2, 3]:
            return Response({'error': '商户已入驻商城,无需重复提交'}, status=status.HTTP_400_BAD_REQUEST)
        if merchant.is_mall == 5:
            return Response({'error': '申请单正在审核中,无需重复提交'}, status=status.HTTP_400_BAD_REQUEST)
        apply = MerchantMallApplyment.objects.filter(merchant_id=merchant.id, applyment_state=1)
        if apply:
            return Response({'error': '申请单正在审核中'}, status=status.HTTP_400_BAD_REQUEST)
        mall_apply_data = {}
        mall_apply_data['signature_copy'] = signature_copy.replace('https://circle.sutpay.cn', '')
        mall_apply_data['contract'] = contract.replace('https://circle.sutpay.cn', '')
        mall_apply_data['context'] = '入驻微邮惠商城申请'
        mall_apply_data['merchant_id'] = merchant.id
        mall_apply_data['applyment_state'] = 1
        instance, create = MerchantMallApplyment.objects.get_or_create(defaults=mall_apply_data, merchant_id=merchant.id, applyment_state=1)
        merchant.is_mall = 5
        merchant.applyment_state = 1
        merchant.verify_state = 0
        merchant.save()
        eta = datetime.datetime.utcnow() + datetime.timedelta(seconds=30)
        # task_id = automatic_audit_mall_applyment.apply_async(({"applyment_id": instance.id},), eta=eta)
        return Response({'success': '提交成功'}, status=status.HTTP_200_OK)

    def applyment(self, request):
        user = self.request.iser
        merchant = self.request.merchant
        instance = MerchantMallApplyment.objects.filter(applyment_state__in=[1, 3, 2], merchant_id=merchant.id).last()
        data = {}
        data['applyment_type_str'] = ''
        data['applyment_type'] = ''
        data['context'] = ''
        data['create_time'] = ''
        data['applyment_state'] = ''
        data['applyment_state_str'] = ''
        data['contract'] = ''
        if instance:
            data['applyment_type_str'] = instance.get_applyment_type_display()
            data['applyment_type'] = instance.applyment_type
            data['context'] = instance.context
            data['create_time'] = instance.create_time.strftime('%Y-%m-%d %H:%M:%S')
            data['applyment_state'] = instance.applyment_state
            data['applyment_state_str'] = instance.get_applyment_state_display()
            try:
                data['contract'] = instance.contract.url
            except:
                data['contract'] = ''
        return Response(data, status=status.HTTP_200_OK)

    def operation_mall(self, request):
        user = self.request.iser
        merchant = self.request.merchant
        if merchant.is_mall not in [2, 3]:
            return Response({'error': '商户尚未通过入驻申请'}, status=status.HTTP_400_BAD_REQUEST)
        if merchant.is_mall == 2:
            merchant.is_mall = 3
            merchant.save()
        else:
            merchant.is_mall = 2
            merchant.save()
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def update_logo(self, request):
        user = self.request.iser
        merchant = self.request.merchant
        img = self.request.FILES.get('img', None)
        if not all([img]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if img.size > 2097152:
            return Response({'error': '照片不得超过2M,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        img_str = img.read()
        img.seek(0)
        try:
            img_id = f'youhuiquanyi/{merchant.wyfMerchantID}/store_logo_copy{"%06d" % randint(0, 999999)}.png'
            mid_img = pic_upload(img_str, key=img_id)
        except Exception as e:
            logger.error(e)
            return Response({'error': '图片上传失败,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            old_store_logo_copy = merchant.store_logo_copy
            pic_delete(old_store_logo_copy)
        except:
            pass
        merchant.store_logo_copy = img_id
        merchant.save()
        merchant = Merchant.objects.get(id=merchant.id)
        return Response({'success': '操作成功', 'store_logo_copy': merchant.store_logo_copy.url}, status=status.HTTP_200_OK)

    def delete_image(self, request):
        user = self.request.iser
        merchant = self.request.merchant
        img_id = self.request.data.get('img_id', None)
        instance = MerchantImage.objects.filter(id=img_id).first()
        try:
            old_store_logo_copy = instance.image
            pic_delete(old_store_logo_copy)
        except:
            pass
        instance.delete()
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def add_image(self, request):
        user = self.request.iser
        merchant = self.request.merchant
        img = self.request.FILES.get('img', None)
        if not all([img]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if img.size > 2097152:
            return Response({'error': '照片不得超过2M,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        img_str = img.read()
        img.seek(0)
        try:
            img_id = f'youhuiquanyi/{merchant.wyfMerchantID}/merchant_image{"%06d" % randint(0, 999999)}.png'
            mid_img = pic_upload(img_str, key=img_id)
        except Exception as e:
            logger.error(e)
            return Response({'error': '图片上传失败,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        instance = MerchantImage.objects.create(merchant_id=merchant.id, image=img_id)
        data = MerchantImageSerializer(instance).data
        return Response({'success': '操作成功', 'img': data}, status=status.HTTP_200_OK)

    def update_merchant(self, request):
        user = self.request.iser
        merchant = self.request.merchant
        managerName = self.request.data.get('managerName', None)
        managermobile = self.request.data.get('managermobile', None)
        short_name = self.request.data.get('short_name', None)
        merchant_desc = self.request.data.get('merchant_desc', None)
        business_category_id = self.request.data.get('business_category_id', None)
        open_work_time = self.request.data.get('open_work_time', None)
        close_work_time = self.request.data.get('close_work_time', None)
        longitude = self.request.data.get('longitude', None)
        latitude = self.request.data.get('latitude', None)
        store_address = self.request.data.get('store_address', None)
        is_online = self.request.data.get('is_online', None)
        prov_name = self.request.data.get('prov_name', None)
        city_name = self.request.data.get('city_name', None)
        district_name = self.request.data.get('district_name', None)
        prov_code = self.request.data.get('prov_code', None)
        city_code = self.request.data.get('city_code', None)
        district_code = self.request.data.get('district_code', None)
        settlement_amount_by_day = self.request.data.get('settlement_amount_by_day', None)
        if managerName:
            merchant.managerName = managerName
        if settlement_amount_by_day:
            merchant.settlement_amount_by_day = settlement_amount_by_day
        if short_name:
            merchant.short_name = short_name
        if merchant_desc:
            merchant.merchant_desc = merchant_desc
        if business_category_id:
            try:
                business_category = MerchantBusinessCategory.objects.get(id=business_category_id)
            except:
                return Response({'error': '无效经营类目'}, status=status.HTTP_400_BAD_REQUEST)
            merchant.business_category_id = business_category_id
        if open_work_time:
            try:
                time.strptime(str(open_work_time), "%H:%M")
            except:
                return Response({'error': '经营时间参数有误!'}, status=status.HTTP_400_BAD_REQUEST)
            busStartTm = f'1900-01-01 {open_work_time}:00'
            merchant.open_work_time = busStartTm
        if close_work_time:
            try:
                time.strptime(str(close_work_time), "%H:%M")
            except:
                return Response({'error': '经营时间参数有误!'}, status=status.HTTP_400_BAD_REQUEST)
            busEndTm = f'1900-01-01 {close_work_time}:00'
            merchant.close_work_time = busEndTm
        if longitude:
            merchant.longitude = longitude
        if latitude:
            merchant.latitude = latitude
        if prov_name:
            merchant.prov_name = prov_name
        if city_name:
            merchant.city_name = city_name
        if district_name:
            merchant.district_name = district_name
        if prov_code:
            merchant.prov_code = prov_code
        if city_code:
            merchant.city_code = city_code
        if district_code:
            merchant.district_code = district_code
        if store_address:
            merchant.store_address = store_address
        if is_online:
            if str(is_online) not in ['1', '2', '3']:
                return Response({'error': '上下架参数有误'}, status=status.HTTP_400_BAD_REQUEST)
            merchant.is_online = is_online
        try:
            merchant.save()
            return Response({'success': '保存成功'}, status=status.HTTP_200_OK)
        except:
            return Response({'error': '保存失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)


class OrderInfoModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    filter_class = OrderInfoFilter

    def get_queryset(self):
        user = self.request.iser
        merchant = self.request.merchant
        search = self.request.query_params.get('search', None)
        queryset = OrderInfo.objects.filter(merchant_id=merchant.id, state__in=[2, 3, 6, 9, 14, 5, 8, 15])
        if search:
            es = Elasticsearch(["http://159.75.55.19:9200/"])
            body = {
                "query": {
                    "bool": {
                        "must": [],
                        "must_not": [],
                        "should": [],
                        # "filter": {
                        #     "ids": {
                        #         "values": ["orders.orderinfo.5418961"]
                        #     }
                        # }
                    }
                },
                "from": 0,
                "size": 10000,
                "sort": [],
                "aggs": {}
            }
            if not search.isdigit():
                filter_data = {
                    "match_phrase_prefix": {
                        "text": search
                    }
                }
                body['query']['bool']['must'].append(filter_data)
            else:
                filter_data = {
                    "wildcard": {
                        "text": f'*{search}*'
                    }
                }
                body['query']['bool']['must'].append(filter_data)
            filter_data = {
                "wildcard": {
                    "text": merchant.wyfMerchantID
                }
            }
            body['query']['bool']['should'].append(filter_data)
            body['query']['bool']['must_not'].append({"wildcard": {"text": "*vm*"}})
            result = es.search(index="equity_mall_order", doc_type="modelresult", body=body)
            # return Response(result)
            hits = result['hits']['hits']
            id_list = []
            for order in hits:
                id_list.append(order['_id'])
            queryset = queryset.filter(id__in=id_list)
        return queryset.order_by('-create_time')

    def get_serializer_class(self):
        if self.action == 'list':
            return OrderInfoListModelSerializer
        else:
            return OrderInfoRetrieveModelSerializer

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        order_count = len(queryset)
        order_amount = queryset.aggregate(Sum('total_price'))['total_price__sum']
        try:
            if '_mutable' in self.request.data.__dict__:
                self.request.data.__dict__['_mutable'] = True
        except:
            pass
        self.request.data['order_count'] = str(order_count)
        self.request.data['order_amount'] = str(order_amount)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    def check_coupon(self, request):
        user = self.request.iser
        coupon_id = self.request.data.get('coupon_id', None)
        if not coupon_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            goodscoupon = GoodsCoupons.objects.get(coupons_id=coupon_id)
        except:
            return Response({'error': '无效核销码'}, status=status.HTTP_400_BAD_REQUEST)
        order = goodscoupon.order
        goods = goodscoupon.goods
        if goods.category_id != 1:
            return Response({'error': '核销码类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        if order.level_id:
            is_can = 0
            try:
                msg = f'*该订单属于{order.level.name}自提订单,您没有该商品的核销权限!'
            except:
                msg = f'*您没有该商品的核销权限!'
            coupon_arr = []
            coupon_list = []
        else:
            if goods.merchant.merchantuser_id != user.id:
                is_can = 0
                msg = f'*您没有该商品的核销权限!'
                coupon_arr = []
                coupon_list = []
            else:
                if goodscoupon.status == 1:
                    is_can = 1
                    msg = ''
                    coupon_arr = [coupon_id]
                    coupon_list = []
                else:
                    goodscoupons_set = GoodsCoupons.objects.filter(order_id=order.id, status=1).exclude(coupons_id=coupon_id)
                    if goodscoupons_set:
                        coupon_arr = []
                        coupon_list = []
                        for goodscoupons in goodscoupons_set:
                            coupon_arr.append(goodscoupons.coupons_id)
                            coupon_list.append({
                                'goods_name': goodscoupons.goods.name,
                                'price': goodscoupons.goods.price,
                                'count': 1
                            })
                        is_can = 2
                        msg = ''
                    else:
                        is_can = 0
                        if goodscoupon.status == 3:
                            msg = '**提货码已过期'
                        elif goodscoupon.status == 4:
                            msg = '**提货码已撤销'
                        else:
                            msg = ''
                        coupon_arr = []
                        coupon_list = []
        data = {}
        data['merchant_name'] = goods.merchant.managerName
        data['goods_name'] = goods.name
        data['default_image'] = goods.default_image.url
        data['count'] = 1
        data['price'] = goods.price
        data['create_time'] = order.create_time.strftime('%Y-%m-%d %H:%M:%S')
        data['mobile'] = order.reserved_mobile
        data['request_date'] = {'coupon_arr': coupon_arr, 'order_id': order.id}
        data['coupon_list'] = coupon_list
        data['is_can'] = is_can
        data['msg'] = msg
        data['status'] = goodscoupon.status
        data['status_str'] = goodscoupon.get_status_display()
        return Response(data, status=status.HTTP_200_OK)

    def use_coupon(self, request):
        user = self.request.iser
        coupon_arr = self.request.data.get('coupon_arr', None)
        order_id = self.request.data.get('order_id', None)
        if not all([coupon_arr, order_id]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if type(coupon_arr) != list:
            return Response({'error': '参数类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            order = OrderInfo.objects.get(id=order_id)
        except:
            return Response({'error': '无效订单号'}, status=status.HTTP_400_BAD_REQUEST)
        if order.state == 3:
            return Response({'error': '订单已无未核销商品,请刷新核实'}, status=status.HTTP_400_BAD_REQUEST)
        if order.level_id:
            return Response({'error': f'该订单属于{order.level.name}自提订单,您没有该商品的核销权限!'}, status=status.HTTP_400_BAD_REQUEST)
        goodscoupons_set = GoodsCoupons.objects.filter(coupons_id__in=coupon_arr, order_id=order_id, status=1)
        for goodscoupons in goodscoupons_set:
            goods = goodscoupons.goods
            if goods.merchant.merchantuser_id != user.id:
                return Response({'error': '您无权核销该订单'}, status=status.HTTP_400_BAD_REQUEST)
        for goodscoupons in goodscoupons_set:
            goodscoupons.status = 2
            goodscoupons.use_time = datetime.datetime.now()
            goodscoupons.use_merchantuser_id = user.id
            goodscoupons.save()
        data = {}
        goodscoupons_set = GoodsCoupons.objects.filter(order_id=order_id, status=1)
        if not goodscoupons_set:
            order.state = 3
            order.use_time = datetime.datetime.now()
            order.merchantuser_id = user.id
            order.save()
            if order.order_type in [1, 7]:
                try:
                    # ordergoods_set = order.ordergoods_set.all().filter(goods__is_settlement=1)
                    # context = ''
                    # for ordergoods in ordergoods_set:
                    #     context = context + f'{ordergoods.goods.name}*{ordergoods.count},'
                    #     receipts_time = datetime.datetime.now().strftime('%Y-%m-%d')
                    #     bill = MerchantBill.objects.filter(receipts_time=receipts_time, merchant_id=ordergoods.merchant_id, bill_type=order.order_species).first()
                    #     if not bill:
                    #         bill_data = {}
                    #         bill_data['merchant_id'] = ordergoods.merchant_id
                    #         bill_data['receipts_time'] = receipts_time
                    #         bill_data['point'] = ordergoods.point
                    #         bill_data['amount'] = ordergoods.price
                    #         bill_data['bill_type'] = order.order_species
                    #         bill_data['payable_amount'] = ordergoods.price + Decimal(int(ordergoods.point) / 100)
                    #         bill, create = MerchantBill.objects.get_or_create(defaults=bill_data,
                    #                                                           receipts_time=receipts_time,
                    #                                                           merchant_id=ordergoods.merchant_id, bill_type=order.order_species)
                    #     else:
                    #         bill.point = bill.point + ordergoods.point
                    #         bill.amount = bill.amount + ordergoods.price
                    #         bill.payable_amount = bill.payable_amount + Decimal(int(ordergoods.point) / 100) + ordergoods.price
                    #         bill.save()
                    #     order.payable_settled_amount = order.payable_settled_amount + Decimal(int(ordergoods.point) / 100) + ordergoods.price
                    #     order.bill_id = bill.id
                    #     order.save()
                    # context = context[:-1] + '(支付宝)'
                    # if order.payable_settled_amount:
                    #     body = {
                    #         "shop_id": order.merchant.ruiyinxinMerchantID,
                    #         "shop_order_id": order.order_id,
                    #         "source": "alipay",
                    #         "money": str(order.payable_settled_amount),
                    #         "context": context
                    #     }
                    #     result = ryx_settle_order(body)
                    #     if result['result_code'] == 'success':
                    #         order.bill_order_id = result['order_id']
                    #         order.save()
                    #     else:
                    #         order.bill_error_msg = result['error_msg']
                    #         order.save()
                    if order.is_profit_sharing == 1:
                        out_trade_no = f'{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}{"%06d" % randint(0, 999999)}'
                        body = {
                            "program_id": "202316837141378884",
                            "shop_id": order.merchant.ruiyinxinMerchantID,
                            "order_id": out_trade_no,
                            "out_trade_no": order.orderNum,
                            "is_profit": "0"
                        }
                        result = ryx_profitsharing_order(body)
                        profitorder = OrderProfitSharing.objects.filter(order_id=order.id).first()
                        if not profitorder:
                            profitorder, create = OrderProfitSharing.objects.get_or_create(defaults={'order_id': order.id, "out_trade_no": out_trade_no}, order_id=order.id)
                        if result['result_code'] == 'success':
                            order.is_profit_sharing = 2
                            order.save()
                            profitorder.profit_order_id = result['profit_order_id']
                            profitorder.profit_time = datetime.datetime.now()
                            profitorder.save()
                            OrderAdvance.objects.create(
                                order_id=order.id,
                                status=5,
                                remark='商户自行核销订单,解冻资金',
                                merchantuser_id=user.id
                            )
                            receipts_time = datetime.datetime.now().strftime('%Y-%m-%d')
                            bill = MerchantBill.objects.filter(receipts_time=receipts_time, merchant_id=order.merchant_id, bill_type=order.order_species).first()
                            if not bill:
                                bill_data = {}
                                bill_data['merchant_id'] = order.merchant_id
                                bill_data['receipts_time'] = receipts_time
                                bill_data['amount'] = order.total_price
                                bill_data['commission'] = order.freight
                                bill_data['level_id'] = order.merchant.level_id
                                bill_data['payable_amount'] = order.total_price - order.freight
                                bill_data['channel_id'] = 3
                                bill_data['bill_type'] = order.order_species
                                bill, create = MerchantBill.objects.get_or_create(defaults=bill_data, receipts_time=receipts_time, merchant_id=order.merchant_id, bill_type=order.order_species)
                            else:
                                bill.amount = bill.amount + order.total_price
                                bill.commission = bill.commission + order.freight
                                bill.payable_amount = bill.payable_amount + order.total_price - order.freight
                                bill.save()
                            order.payable_settled_amount = order.total_price - order.freight
                            order.bill_id = bill.id
                            order.save()
                        else:
                            order.is_profit_sharing = 2
                            order.save()
                            profitorder.error_msg = result['error_msg']
                            profitorder.profit_status = 2
                            profitorder.save()
                            OrderAdvance.objects.create(
                                order_id=order.id,
                                status=4,
                                remark='商户自行核销订单,解冻资金出错',
                                merchantuser_id=user.id
                            )
                    elif order.is_profit_sharing == 3:
                        out_trade_no = f'{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}{"%06d" % randint(0, 999999)}'
                        body = {
                            "program_id": "202316837141378884",
                            "shop_id": order.merchant.ruiyinxinMerchantID,
                            "order_id": out_trade_no,
                            "out_trade_no": order.orderNum,
                            "is_profit": "2"
                        }
                        result = ryx_profitsharing_order(body)
                        profitorder = OrderProfitSharing.objects.filter(order_id=order.id).first()
                        if not profitorder:
                            profitorder, create = OrderProfitSharing.objects.get_or_create(defaults={'order_id': order.id, "out_trade_no": out_trade_no}, order_id=order.id)
                        if result['result_code'] == 'success':
                            order.is_profit_sharing = 4
                            order.save()
                            profitorder.profit_order_id = result['profit_order_id']
                            profitorder.profit_time = datetime.datetime.now()
                            profitorder.save()
                            OrderAdvance.objects.create(
                                order_id=order.id,
                                status=5,
                                remark='商户自行核销订单,解冻资金',
                                merchantuser_id=user.id
                            )
                            receipts_time = datetime.datetime.now().strftime('%Y-%m-%d')
                            bill = MerchantBill.objects.filter(receipts_time=receipts_time, merchant_id=order.merchant_id, bill_type=order.order_species).first()
                            if not bill:
                                bill_data = {}
                                bill_data['merchant_id'] = order.merchant_id
                                bill_data['receipts_time'] = receipts_time
                                bill_data['amount'] = order.total_price
                                bill_data['commission'] = order.freight
                                bill_data['level_id'] = order.merchant.level_id
                                bill_data['payable_amount'] = order.total_price - order.freight
                                bill_data['channel_id'] = 3
                                bill_data['bill_type'] = order.order_species
                                bill, create = MerchantBill.objects.get_or_create(defaults=bill_data, receipts_time=receipts_time, merchant_id=order.merchant_id, bill_type=order.order_species)
                            else:
                                bill.amount = bill.amount + order.total_price
                                bill.commission = bill.commission + order.freight
                                bill.payable_amount = bill.payable_amount + order.total_price - order.freight
                                bill.save()
                            order.payable_settled_amount = order.total_price - order.freight
                            order.bill_id = bill.id
                            order.save()
                        else:
                            order.is_profit_sharing = 4
                            order.save()
                            profitorder.error_msg = result['error_msg']
                            profitorder.profit_status = 2
                            profitorder.save()
                            OrderAdvance.objects.create(
                                order_id=order.id,
                                status=4,
                                remark='商户自行核销订单,解冻资金出错',
                                merchantuser_id=user.id
                            )
                except Exception as e:
                    logger.error(e)
                    pass
        coupon_arr = []
        coupon_list = []
        for goodscoupons in goodscoupons_set:
            coupon_arr.append(goodscoupons.coupons_id)
            coupon_list.append({
                'goods_name': goodscoupons.goods.name,
                'price': goodscoupons.goods.price,
                'count': 1
            })
        data['request_date'] = {'coupon_arr': coupon_arr, 'order_id': order.id}
        data['coupon_list'] = coupon_list
        return Response(data, status=status.HTTP_200_OK)

    def add_express(self, request, *args, **kwargs):
        user = self.request.iser
        express_array = self.request.data.get('express_array', None)
        order_id = self.request.data.get('order_id', None)
        if not all([express_array, order_id]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=order_id)
        except:
            return Response({'error': '无效订单id'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.state not in [6, 9]:
            return Response({'error': '订单状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                for express in express_array:
                    try:
                        ExpressType.objects.get(id=express['express_type_id'])
                    except:
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': '无效快递类型'}, status=status.HTTP_400_BAD_REQUEST)
                    express_data = {}
                    express_data['express_type_id'] = express['express_type_id']
                    express_data['express_number'] = express['express_number']
                    express, create = Express.objects.get_or_create(defaults=express_data, express_number=express['express_number'])
                    relevance_data = {}
                    relevance_data['order_id'] = instance.id
                    relevance_data['express_id'] = express.id
                    ExpressOrderRelevance.objects.get_or_create(defaults=relevance_data, order_id=relevance_data['order_id'], express_id=relevance_data['express_id'])
                instance.state = 6
                instance.save()
                OrderAdvance.objects.create(
                    order_id=instance.id,
                    status=3,
                    remark='添加快递单号',
                    merchantuser_id=user.id
                )
                try:
                    express_send.delay({'id': instance.id, 'express_id': express.id})
                except:
                    pass
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                return Response({'error': '操作失败'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
            return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def delete_express(self,request):
        user = self.request.iser
        express_id = self.request.data.get('express_id', None)
        order_id = self.request.data.get('order_id', None)
        if not all([order_id, express_id]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=order_id)
        except:
            return Response({'error': '无效订单id'}, status=status.HTTP_400_BAD_REQUEST)
        check_advance_count = OrderAdvance.objects.filter(order_id=instance.id, merchantuser_id=user.id, remark='解绑快递单号').count()
        if check_advance_count >= 3:
            return Response({'error': '解绑失败,超过最大解绑次数'}, status=status.HTTP_400_BAD_REQUEST)
        delete_instance = ExpressOrderRelevance.objects.filter(order_id=order_id, express_id=express_id)
        if not delete_instance:
            return Response({'error': '解绑失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        delete_instance.delete()
        check_relevance = ExpressOrderRelevance.objects.filter(order_id=order_id)
        if not check_relevance:
            instance.state = 9
            instance.save()
        OrderAdvance.objects.create(
            order_id=instance.id,
            status=3,
            remark='解绑快递单号',
            merchantuser_id=user.id
        )
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def export_orderinfo(self, request):
        user = self.request.iser
        merchant = self.request.merchant
        create_time_begin = self.request.query_params.get('create_time_begin', None)
        create_time_end = self.request.query_params.get('create_time_end', None)
        payment_time_begin = self.request.query_params.get('payment_time_begin', None)
        payment_time_end = self.request.query_params.get('payment_time_end', None)
        use_time_begin = self.request.query_params.get('use_time_begin', None)
        use_time_end = self.request.query_params.get('use_time_end', None)
        total_price_min = self.request.query_params.get('total_price_min', None)
        total_price_max = self.request.query_params.get('total_price_max', None)
        state = self.request.query_params.get('state', None)
        search = self.request.query_params.get('search', None)
        condition = f'WHERE merchant_id={merchant.id} AND state IN (2, 3, 6, 9, 14, 5, 8, 15)'
        if search:
            es = Elasticsearch(["http://159.75.55.19:9200/"])
            body = {
                "query": {
                    "bool": {
                        "must": [],
                        "must_not": [],
                        "should": []
                    }
                },
                "from": 0,
                "size": 10000,
                "sort": [],
                "aggs": {}
            }
            if not search.isdigit():
                filter_data = {
                    "match_phrase_prefix": {
                        "text": search
                    }
                }
                body['query']['bool']['must'].append(filter_data)
            else:
                filter_data = {
                    "wildcard": {
                        "text": f'*{search}*'
                    }
                }
                body['query']['bool']['must'].append(filter_data)
            filter_data = {
                "wildcard": {
                    "text": merchant.wyfMerchantID
                }
            }
            body['query']['bool']['should'].append(filter_data)
            body['query']['bool']['must_not'].append({"wildcard": {"text": "*vm*"}})
            result = es.search(index="equity_mall_order", doc_type="modelresult", body=body)
            # return Response(result)
            hits = result['hits']['hits']
            id_list = []
            for order in hits:
                id_list.append(order['_id'])
            if id_list:
                if len(id_list) == 1:
                    condition = condition + f' AND id IN {tuple(id_list)}'.replace(',', '')
                else:
                    condition = condition + f' AND id IN {tuple(id_list)}'
            # condition = condition + f' AND (id in (SELECT order_id FROM tb_order_goods WHERE merchant_id IN (SELECT id FROM tb_merchant WHERE name LIKE "%{search}%") OR goods_id IN (SELECT id FROM tb_goods WHERE name LIKE "%{search}%") OR customer_user_id IN (SELECT id FROM tb_u_customer_user WHERE mobile LIKE "%{search}%")))'
        if create_time_begin:
            condition = condition + f' AND create_time >= "{create_time_begin + " 00:00:00"}"'
        if create_time_end:
            condition = condition + f' AND create_time <= "{create_time_end + " 23:59:59"}"'
        if payment_time_begin:
            condition = condition + f' AND payment_time >= "{payment_time_begin + " 00:00:00"}"'
        if payment_time_end:
            condition = condition + f' AND payment_time <= "{payment_time_end + " 23:59:59"}"'
        if use_time_begin:
            condition = condition + f' AND use_time >= "{use_time_begin + " 00:00:00"}"'
        if use_time_end:
            condition = condition + f' AND use_time <= "{use_time_end + " 23:59:59"}"'
        if total_price_min:
            condition = condition + f' AND total_price >= "{total_price_min}"'
        if total_price_max:
            condition = condition + f' AND total_price <= "{total_price_max}"'
        if state:
            condition = condition + f' AND state in ({state})'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        try:
            sql = f'''
            SELECT t.*,u.address_mobile,receiver,province,city,district,place FROM (SELECT r.*,s.vice_mobile,vice_realname FROM (SELECT p.*,q.account,level_name,merchant_name,wyfMerchantID FROM (SELECT l.*,m.goods_name,goods_count,goods_price FROM (SELECT g.*,h.coupons_id,coupons_status,coupons_use_time FROM (SELECT c.*,d.customer_level,mobile,realname FROM (SELECT a.*, b.name FROM (SELECT id,level_id,state,total_price,total_point,(total_price-realpay_amount)AS coupons_amount,realpay_amount,customer_user_id,orderNum,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S') AS create_time,DATE_FORMAT(payment_time,'%Y-%m-%d %H:%i:%S') AS payment_time,merchant_id,order_id,trade_no,customeruservice_id FROM tb_order_info {condition})AS a LEFT JOIN (SELECT id,name FROM tb_u_level)AS b ON a.level_id=b.id)AS c LEFT JOIN (SELECT e.*,f.customer_level FROM (SELECT id,mobile,realname,level_id FROM tb_u_customer_user)AS e LEFT JOIN (SELECT id,CONCAT(prov_name,'-',city_name,'-',district_name,'-',branch_name)AS customer_level FROM tb_u_level)AS f ON e.level_id=f.id)AS d ON c.customer_user_id=d.id)AS g LEFT JOIN (SELECT GROUP_CONCAT(coupons_id)AS coupons_id,GROUP_CONCAT(status)AS coupons_status,GROUP_CONCAT(DATE_FORMAT(use_time,'%Y-%m-%d %H:%i:%S'))AS coupons_use_time,order_id FROM tb_goods_coupons WHERE order_id IN (SELECT id FROM tb_order_info {condition}) GROUP BY order_id)AS h ON g.id=h.order_id)AS l LEFT JOIN (SELECT GROUP_CONCAT(k.name)AS goods_name,GROUP_CONCAT(k.count)AS goods_count,GROUP_CONCAT(k.price)AS goods_price,order_id FROM (SELECT i.price,count,order_id,j.name FROM (SELECT * FROM tb_order_goods WHERE order_id IN (SELECT id FROM tb_order_info {condition}))AS i LEFT JOIN (SELECT * FROM tb_goods)AS j ON i.goods_id=j.id)AS k GROUP BY order_id)AS m ON l.id=m.order_id)AS p LEFT JOIN (SELECT n.*,o.account,level_name FROM (SELECT id,name AS merchant_name,wyfMerchantID,level_id FROM tb_merchant)AS n LEFT JOIN (SELECT id,name AS level_name,account FROM tb_u_level)AS o ON n.level_id=o.id)AS q ON p.merchant_id=q.id)AS r LEFT JOIN (SELECT id,mobile AS vice_mobile,realname AS vice_realname FROM tb_u_customer_user_vice WHERE id IN (SELECT customeruservice_id FROM tb_order_info {condition}))AS s ON r.customeruservice_id=s.id)AS t LEFT JOIN (SELECT receiver,province,city,district,place,mobile AS address_mobile,order_id FROM tb_order_address WHERE order_id IN (SELECT id FROM tb_order_info {condition}))AS u ON t.id=u.order_id;
            '''
            cursor.execute(sql)
        except Exception as e:
            sql = f'''
            SELECT p.*,q.account,level_name,merchant_name,wyfMerchantID FROM (SELECT l.*,m.goods_name,goods_count,goods_price FROM (SELECT g.*,h.coupons_id,coupons_status,coupons_use_time FROM (SELECT c.*,d.customer_level,mobile,realname FROM (SELECT a.*, b.name FROM (SELECT id,level_id,state,total_price,total_point,(total_price-realpay_amount)AS coupons_amount,realpay_amount,customer_user_id,orderNum,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S') AS create_time,merchant_id,order_id,trade_no FROM tb_order_info WHERE id=1)AS a LEFT JOIN (SELECT id,name FROM tb_u_level)AS b ON a.level_id=b.id)AS c LEFT JOIN (SELECT e.*,f.customer_level FROM (SELECT id,mobile,realname,level_id FROM tb_u_customer_user)AS e LEFT JOIN (SELECT id,CONCAT(prov_name,'-',city_name,'-',district_name,'-',branch_name)AS customer_level FROM tb_u_level)AS f ON e.level_id=f.id)AS d ON c.customer_user_id=d.id)AS g LEFT JOIN (SELECT GROUP_CONCAT(coupons_id)AS coupons_id,GROUP_CONCAT(status)AS coupons_status,GROUP_CONCAT(DATE_FORMAT(use_time,'%Y-%m-%d %H:%i:%S'))AS coupons_use_time,order_id FROM tb_goods_coupons GROUP BY order_id)AS h ON g.id=h.order_id)AS l LEFT JOIN (SELECT GROUP_CONCAT(k.name)AS goods_name,GROUP_CONCAT(k.count)AS goods_count,GROUP_CONCAT(k.price)AS goods_price,order_id FROM (SELECT i.price,count,order_id,j.name FROM (SELECT * FROM tb_order_goods)AS i LEFT JOIN (SELECT * FROM tb_goods)AS j ON i.goods_id=j.id)AS k GROUP BY order_id)AS m ON l.id=m.order_id)AS p LEFT JOIN (SELECT n.*,o.account,level_name FROM (SELECT id,name AS merchant_name,wyfMerchantID,level_id FROM tb_merchant)AS n LEFT JOIN (SELECT id,name AS level_name,account FROM tb_u_level)AS o ON n.level_id=o.id)AS q ON p.merchant_id=q.id;
            '''
            cursor.execute(sql)
        ziduan = ['id', '平台订单号', '订单号', '支付流水号', '下单时间', '商品名称', '单价', '数量', '总金额(元)', '商家信息', '微邮付商户号', '所属机构', '所属机构号', '购买网点', '订单状态', '付款时间', '邮米抵扣', '优惠券抵扣(元)', '实付金额(元)', '券码', '券码状态', '券码核销时间', '购买用户手机号', '用户真实姓名', '用户归属', '收货人', '收货人手机号', '收货地址']
        cols = ['id', 'order_id', 'orderNum', 'trade_no', 'create_time', 'goods_name', 'goods_price', 'goods_count', 'total_price', 'merchant_name', 'wyfMerchantID', 'level_name', 'account', 'name', 'state', 'payment_time', 'total_point', 'coupons_amount', 'realpay_amount', 'coupons_id', 'coupons_status', 'coupons_use_time', 'mobile', 'realname', 'customer_level', 'receiver', 'address_mobile', 'place']
        response = StreamingHttpResponse(self.get_orderinfo_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('订单列表.csv'))
        return response

    def get_orderinfo_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        STATUS_ENUM = {
            0: '待付款',
            1: '待付款',
            2: '待核销',
            3: '已核销',
            4: '订单过期',
            5: '售后中',
            6: '已发货',
            7: '已预约',
            8: '已退款',
            9: '发货中',
            10: '退款中',
            11: '订单异常',
            12: '已付款',
            13: '已取消',
            14: '已完成'
        }
        COUPONS_STATUS_ENUM = {
            "0": '未激活',
            "1": '待核销',
            "2": '已核销',
            "3": '已过期',
            "4": '已撤销'
        }
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col == 'state':
                    tmp_str += '"%s",' % (STATUS_ENUM[row[col]])
                elif col == 'coupons_status':
                    coupons_status_str = ''
                    if row[col]:
                        coupons_status_list = row[col].split(',')
                        for coupons_status in coupons_status_list:
                            coupons_status_str += COUPONS_STATUS_ENUM[coupons_status]
                            coupons_status_str += ','
                    tmp_str += '"%s",' % (coupons_status_str)
                elif col in ['mobile', 'realname']:
                    if row['customeruservice_id']:
                        tmp_str += '"%s",' % (str(row[f'vice_{col}']).encode('GBK', 'ignore').decode('gbk') if row[f'vice_{col}'] else '')
                    else:
                        tmp_str += '"%s",' % (str(row[f'{col}']).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                elif col == 'place':
                    tmp_str += '"%s",' % (str(f'{row["province"]}-{row["city"]}-{row["district"]}-{row[col]}').encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                elif col in ['orderNum', 'trade_no', 'coupons_id', 'order_id']:
                    tmp_str += '"\'%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                elif col in ['total_price', 'total_point', 'coupons_amount', 'realpay_amount']:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else 0)
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"

    def batch_add_express(self, request):
        user = self.request.iser
        check_history = ExpressQuest.objects.filter(is_enter=1)
        if check_history:
            is_enter = 4
        else:
            is_enter = 1
        my_file = self.request.FILES.get('my_file', None)
        if not my_file:
            return Response({'error': '请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
        type_excel = my_file.name.split('.')[-1]
        file_contents = my_file.read()
        if type_excel not in ['xlsx', 'xls']:
            return Response({'error': '文件格式有误, 请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            wb = xlrd.open_workbook(filename=None, file_contents=file_contents)  # 关键点在于这里
        except:
            return Response({'error': '文件格式有误, 请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
        table = wb.sheets()[0]
        nrows = table.nrows - 1
        title = table.row_values(0)
        if '订单号' not in title:
            return Response({'error': '表格字段缺少"订单号"'}, status=status.HTTP_400_BAD_REQUEST)
        if '快递单号' not in title:
            return Response({'error': '表格字段缺少"快递单号"'}, status=status.HTTP_400_BAD_REQUEST)
        if '快递类型' not in title:
            return Response({'error': '表格字段缺少"快递类型"'}, status=status.HTTP_400_BAD_REQUEST)
        file_name = f'{my_file.name.replace(type_excel, "").replace(".", "")}_{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}.{type_excel}'
        file = pic_upload(file_contents, file_name)
        history = ExpressQuest.objects.create(merchantuser_id=user.id, file=file, is_enter=is_enter, line_number=nrows)
        if is_enter == 1:
            # execute_express_quest({'id': history.id})
            execute_express_quest.delay({'id': history.id})
        return Response({'success': '上传文件成功'}, status=status.HTTP_200_OK)


class ExpressTypeModelViewSet(ModelViewSet):

    queryset = ExpressType.objects.all()
    serializer_class = ExpressTypeModelSerializer
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('express_type_name', )

    def choices_expresstype(self, request):
        express_number = self.request.query_params.get('express_number', '')
        url = f'https://alayn.baidu.com/express/appdetail/get_com?num={express_number}'
        response = requests.get(url=url)
        try:
            result = response.json()
            express_type = ExpressType.objects.filter(express_type=result['data']['company']).first()
            if express_type:
                return Response(ExpressTypeModelSerializer(express_type).data, status=status.HTTP_200_OK)
            else:
                return Response({}, status=status.HTTP_200_OK)
        except:
            return Response({}, status=status.HTTP_200_OK)


class ExpressModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    filter_class = ExpressFilter
    search_fields = ('express_number',)

    def get_queryset(self):
        user = self.request.iser
        merchant = self.request.merchant
        queryset = Express.objects.filter(expressorderrelevance__order__merchant_id=merchant.id).distinct().order_by('-id')
        return queryset

    def get_serializer_class(self):
        if self.action == 'list':
            return ExpressListModelSerializer
        else:
            return ExpressRetrieveModelSerializer

    def export_express(self, request):
        user = self.request.iser
        merchant = self.request.merchant
        deliverystatus = self.request.query_params.get('deliverystatus', None)
        create_time_begin = self.request.query_params.get('create_time_begin', None)
        create_time_end = self.request.query_params.get('create_time_end', None)
        sign_time_begin = self.request.query_params.get('sign_time_begin', None)
        sign_time_end = self.request.query_params.get('sign_time_end', None)
        search = self.request.query_params.get('search', None)
        condition = f'WHERE id IN (SELECT express_id FROM tb_order_express_relevance WHERE order_id IN (SELECT id FROM tb_order_info WHERE merchant_id={merchant.id}))'
        if search:
            condition = condition + f' AND express_number LIKE "%{search}%"'
        if create_time_begin:
            condition = condition + f' AND create_time >= "{create_time_begin + " 00:00:00"}"'
        if create_time_end:
            condition = condition + f' AND create_time <= "{create_time_end + " 23:59:59"}"'
        if sign_time_begin:
            condition = condition + f' AND sign_time >= "{sign_time_begin + " 00:00:00"}"'
        if sign_time_end:
            condition = condition + f' AND sign_time <= "{sign_time_end + " 23:59:59"}"'
        if deliverystatus:
            condition = condition + f' AND deliverystatus IN ({deliverystatus})'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        try:
            sql = f'''
            SELECT c.*,d.express_type_name FROM (SELECT a.*,b.order_id FROM (SELECT id,express_number,deliverystatus,express_type_id,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S') AS create_time,DATE_FORMAT(sign_time,'%Y-%m-%d %H:%i:%S') AS sign_time FROM tb_order_express {condition})AS a LEFT JOIN (SELECT express_id,GROUP_CONCAT(order_id)AS order_id FROM tb_order_express_relevance GROUP BY express_id)AS b ON a.id=b.express_id)AS c LEFT JOIN (SELECT id,express_type_name FROM tb_order_express_type)AS d ON c.express_type_id=d.id;
            '''
            cursor.execute(sql)
        except Exception as e:
            sql = f'''
            SELECT c.*,d.express_type_name FROM (SELECT a.*,b.order_id FROM (SELECT id,express_number,deliverystatus,express_type_id,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S') AS create_time,DATE_FORMAT(sign_time,'%Y-%m-%d %H:%i:%S') AS sign_time FROM tb_order_express)AS a LEFT JOIN (SELECT express_id,GROUP_CONCAT(order_id)AS order_id FROM tb_order_express_relevance GROUP BY express_id)AS b ON a.id=b.express_id)AS c LEFT JOIN (SELECT id,express_type_name FROM tb_order_express_type)AS d ON c.express_type_id=d.id;
            '''
            cursor.execute(sql)
        ziduan = ['id', '快递公司', '快递单号', '快递状态', '录入时间', '签收时间', '订单id']
        cols = ['id', 'express_type_name', 'express_number', 'deliverystatus', 'create_time', 'sign_time', 'order_id']
        response = StreamingHttpResponse(self.get_express_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('快递信息.csv'))
        return response

    def get_express_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        DELIVERYSTATUS_ENUM = {
            0: '在途',
            1: '揽收',
            2: '疑难',
            3: '已签收',
            4: '签退',
            5: '派件',
            6: '退回',
            7: '转投',
            8: '清关',
            9: '错误',
            14: '拒签'
        }
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col == 'deliverystatus':
                    tmp_str += '"%s",' % (DELIVERYSTATUS_ENUM[row[col]])
                elif col in ['express_number']:
                    tmp_str += '\'"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk').replace('\n', '') if row[col] else '')
                elif col in ['order_id']:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk').replace(',', '，') if row[col] else '')
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"


class ExpressQuestModelViewSet(ModelViewSet):

    pagination_class = MyPage

    def get_queryset(self):
        user = self.request.iser
        merchant = self.request.merchant
        queryset = ExpressQuest.objects.filter(merchantuser_id=user.id).order_by('-id')
        return queryset

    def get_serializer_class(self):
        return ExpressQuestListModelSerializer


class GoodsCategoryModelViewSet(ModelViewSet):

    serializer_class = GoodsCategoryModelSerializer
    queryset = GoodsCategory.objects.all()
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', )


class GoodsModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', )
    filter_class = GoodsFilter

    def get_serializer_class(self):
        if self.action == 'list':
            return GoodsListModelSerializer
        else:
            return GoodsRetrieveModelSerializer

    def get_queryset(self):
        user = self.request.iser
        merchant = self.request.merchant
        sale_sort = self.request.query_params.get('sale_sort', None)
        price_sort = self.request.query_params.get('price_sort', None)
        soldout = self.request.query_params.get('soldout', '')
        if soldout == '1':
            queryset = Goods.objects.filter(stock__gt=0, merchant_id=merchant.id).distinct().order_by('-stock')
        elif soldout == '2':
            queryset = Goods.objects.filter(stock=0, merchant_id=merchant.id).distinct().order_by('-stock')
        else:
            queryset = Goods.objects.filter(merchant_id=merchant.id).distinct().order_by('-stock')
        if sale_sort == '1':
            queryset = queryset.order_by('sales', 'id')
        elif sale_sort == '2':
            queryset = queryset.order_by('-sales', 'id')
        if price_sort == '1':
            queryset = queryset.order_by('price', 'id')
        elif price_sort == '2':
            queryset = queryset.order_by('-price', 'id')
        return queryset.filter(equityID__isnull=True)

    def get_serializer_context(self):
        alidiscountcoupon_id = self.request.query_params.get('alidiscountcoupon_id', None)
        return {"alidiscountcoupon_id": alidiscountcoupon_id}

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        user = self.request.iser
        merchant = self.request.merchant
        if merchant:
            store_address = merchant.store_address
        else:
            store_address = ''
        try:
            if '_mutable' in self.request.data.__dict__:
                self.request.data.__dict__['_mutable'] = True
        except:
            pass
        self.request.data['store_address'] = str(store_address)
        is_launched = self.request.query_params.get('is_launched', None)
        if is_launched in ['0', '1']:
            if is_launched == '0':
                queryset = queryset.exclude(is_launched=1)
            else:
                queryset = queryset.filter(is_launched=1)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    def upload_image(self, request):
        user = self.request.iser
        merchant = self.request.merchant
        img = self.request.FILES.get('img', None)
        if not all([img]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if img.size > 2097152:
            return Response({'error': '照片不得超过2M,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        img_str = img.read()
        img.seek(0)
        try:
            img_id = f'youhuiquanyi/{merchant.wyfMerchantID}/goods_image{"%06d" % randint(0, 999999)}.png'
            mid_img = pic_upload(img_str, key=img_id)
        except Exception as e:
            logger.error(e)
            return Response({'error': '图片上传失败,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'success': '操作成功', 'img_id': f'https://circle.sutpay.cn/{img_id}'}, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        user = self.request.iser
        if instance.is_launched == 2:
            return Response({'error': '已存在待审核修改单,请耐心等待客服审核'}, status=status.HTTP_400_BAD_REQUEST)
        applyment = GoodsModifyApplyment.objects.filter(goods_id=instance.id, applyment_status=1)
        if applyment:
            return Response({'error': '已存在待审核修改单,请耐心等待客服审核'}, status=status.HTTP_400_BAD_REQUEST)
        name = self.request.data.get('name', None)
        caption = self.request.data.get('caption', None)
        desc_detail = self.request.data.get('desc_detail', None)
        price = self.request.data.get('price', None)
        market_price = self.request.data.get('market_price', None)
        default_image = self.request.data.get('default_image', None)
        image_array = self.request.data.get('image_array', None)
        stock = self.request.data.get('stock', None)
        manufacturer = self.request.data.get('manufacturer', None)
        specifications = self.request.data.get('specifications', None)
        is_launched = self.request.data.get('is_launched', None)
        if not name:
            return Response({'error': '请输入商品名称。'}, status=status.HTTP_400_BAD_REQUEST)
        if len(name) > 128:
            return Response({'error': '您输入的商品名称有误，请重新输入。'}, status=status.HTTP_400_BAD_REQUEST)
        if not caption:
            return Response({'error': '请输入商品品牌。'}, status=status.HTTP_400_BAD_REQUEST)
        if len(caption) > 50:
            return Response({'error': '您输入的品牌有误，请重新输入。'}, status=status.HTTP_400_BAD_REQUEST)
        if not desc_detail:
            return Response({'error': '请输入商品介绍。'}, status=status.HTTP_400_BAD_REQUEST)
        if not default_image:
            return Response({'error': '请输入商品封面图。'}, status=status.HTTP_400_BAD_REQUEST)
        if not manufacturer:
            return Response({'error': '请输入商品厂商。'}, status=status.HTTP_400_BAD_REQUEST)
        if len(manufacturer) > 32:
            return Response({'error': '您输入的厂商有误，请重新输入。'}, status=status.HTTP_400_BAD_REQUEST)
        if not specifications:
            return Response({'error': '请输入商品规格。'}, status=status.HTTP_400_BAD_REQUEST)
        if len(specifications) > 8:
            return Response({'error': '您输入的商品规格有误，请重新输入。'}, status=status.HTTP_400_BAD_REQUEST)
        if not image_array:
            return Response({'error': '请输入商品轮播图。'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            desc_detail = json.dumps(desc_detail)
            # image_array = json.dumps(image_array)
        except:
            return Response({'error': '商品详情数据格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        applyment_status = 0
        old_goods = GoodsRetrieveModelSerializer(instance).data
        check_word = ['name', 'desc_detail', 'price', 'default_image', 'manufacturer', 'specifications', 'market_price', 'caption']
        update_word = []
        try:
            if old_goods['goodsimage_set'] != self.request.data.get('image_array', None):
                applyment_status = 1
                update_word.append('goodsimage_set')
        except:
            pass
        for word in check_word:
            try:
                if word in ['price', 'market_price']:
                    if Decimal(old_goods[word]) != Decimal(self.request.data.get(word, None)):
                        applyment_status = 1
                        update_word.append(word)
                else:
                    if old_goods[word] != self.request.data.get(word, None):
                        applyment_status = 1
                        update_word.append(word)
            except:
                pass
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                if applyment_status:
                    instance.name = name
                    instance.caption = caption
                    instance.desc_detail = desc_detail
                    instance.price = price
                    instance.market_price = market_price
                    instance.default_image = default_image.replace('https://circle.sutpay.cn/', '')
                    instance.manufacturer = manufacturer
                    instance.specifications = specifications
                    # instance.is_launched = is_launched
                    instance.remain_stock = instance.remain_stock + Decimal(stock) - instance.stock
                    instance.stock = Decimal(stock)
                    instance.save()
                    applyment_data = {}
                    for word in update_word:
                        if word != 'goodsimage_set':
                            applyment_data[word] = old_goods[word]
                    if old_goods['goodsimage_set'] != self.request.data.get('image_array', None):
                        goodsimage_set = instance.goodsimage_set.all().delete()
                        applyment_data['image_array'] = json.dumps(old_goods['goodsimage_set'])
                        for image in image_array:
                            GoodsImage.objects.create(
                                goods_id=instance.id,
                                image=image.replace('https://circle.sutpay.cn/', '')
                            )
                    applyment_data['create_time'] = datetime.datetime.now()
                    applyment_data['is_launched'] = old_goods['is_launched']
                    applyment_data['stock'] = old_goods['stock']
                    applyment_data['goods_id'] = instance.id
                    applyment_data['applyment_status'] = 2
                    # applyment_data['companyuser_id'] = user.id
                    # applyment_data['level_id'] = user.level_id
                    applyment_data['update_word'] = json.dumps(update_word)
                    # applyment, create = GoodsModifyApplyment.objects.get_or_create(goods_id=instance.id, applyment_status=2, defaults=applyment_data)
                    applyment = GoodsModifyApplyment.objects.create(**applyment_data)
                    # eta = datetime.datetime.utcnow() + datetime.timedelta(seconds=3)
                    # task_id = automatic_audit_applyment.apply_async(({"applyment_id": applyment.id},), eta=eta)
                    transaction.savepoint_commit(save_id)
                    return Response({'success': '提交修改成功,请耐心等待客服审核生效'}, status=status.HTTP_200_OK)
                else:
                    instance.remain_stock = instance.remain_stock + Decimal(stock) - instance.stock
                    instance.stock = Decimal(stock)
                    # instance.is_launched = is_launched
                    instance.save()
                    check_query = LaunchedGoods.objects.filter(goods_id=instance.id, is_self=1).first()
                    if not check_query:
                        launched_goods_data = {}
                        launched_goods_data['name'] = instance.name
                        launched_goods_data['caption'] = instance.caption
                        launched_goods_data['goods_id'] = instance.id
                        launched_goods_data['category_id'] = instance.category_id
                        launched_goods_data['price'] = instance.price
                        launched_goods_data['point'] = instance.point
                        launched_goods_data['stock'] = instance.stock
                        launched_goods_data['is_launched'] = 0
                        launched_goods_data['create_time'] = datetime.datetime.now()
                        launched_goods_data['is_self'] = 1
                        LaunchedGoods.objects.get_or_create(defaults=launched_goods_data, goods_id=instance.id, is_self=1)
                    else:
                        check_query.stock = Decimal(stock)
                        check_query.is_launched = is_launched
                        check_query.save()
                    applyment_data = {}
                    applyment_data['stock'] = old_goods['stock']
                    applyment_data['is_launched'] = old_goods['is_launched']
                    applyment_data['applyment_status'] = 2
                    applyment_data['create_time'] = datetime.datetime.now()
                    applyment = GoodsModifyApplyment.objects.create(**applyment_data)
                    transaction.savepoint_commit(save_id)
                    return Response({'success': '提交修改成功'}, status=status.HTTP_200_OK)
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                return Response({'error': '提交失败,请联系管理员处理。'}, status=status.HTTP_400_BAD_REQUEST)

    def create(self, request, *args, **kwargs):
        user = self.request.iser
        merchant = self.request.merchant
        name = self.request.data.get('name', None)
        caption = self.request.data.get('caption', None)
        desc_detail = self.request.data.get('desc_detail', None)
        price = self.request.data.get('price', None)
        market_price = self.request.data.get('market_price', None)
        default_image = self.request.data.get('default_image', None)
        image_array = self.request.data.get('image_array', None)
        stock = self.request.data.get('stock', None)
        manufacturer = self.request.data.get('manufacturer', None)
        specifications = self.request.data.get('specifications', None)
        is_launched = self.request.data.get('is_launched', None)
        barcode = self.request.data.get('barcode', None)
        if not all([name, caption, desc_detail, price, market_price, default_image, image_array, stock, manufacturer, specifications]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            desc_detail = json.dumps(desc_detail)
            # image_array = json.dumps(image_array)
        except:
            return Response({'error': '商品详情数据格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        if merchant.is_mall not in [2, 3]:
            return Response({"error": "商户未入驻微邮惠商城"}, status=status.HTTP_400_BAD_REQUEST)
        instance = Goods.objects.filter(merchant_id=merchant.id, name=name)
        if instance:
            return Response({"error": "商品名称重复"}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                goods_data = {}
                goods_data['name'] = name
                goods_data['caption'] = caption
                goods_data['category_id'] = 1
                goods_data['desc_detail'] = desc_detail
                goods_data['price'] = price
                goods_data['market_price'] = market_price
                goods_data['default_image'] = default_image.replace('https://circle.sutpay.cn/', '')
                goods_data['stock'] = stock
                goods_data['merchant_id'] = merchant.id
                goods_data['manufacturer'] = manufacturer
                goods_data['specifications'] = specifications
                goods_data['is_launched'] = 2
                goods_data['remain_stock'] = stock
                goods_data['is_settlement'] = 1
                goods_data['order_species'] = 2
                instance, create = Goods.objects.get_or_create(defaults=goods_data, name=name, merchant_id=merchant.id)
                for image in image_array:
                    GoodsImage.objects.create(
                        goods_id=instance.id,
                        image=image.replace('https://circle.sutpay.cn/', '')
                    )
                applyment_data = {}
                applyment_data['goods_id'] = instance.id
                applyment_data['merchant_id'] = merchant.id
                applyment_data['applyment_type'] = 2
                applyment_data['barcode'] = barcode
                applyment_data['create_time'] = datetime.datetime.now()
                applyment = GoodsModifyApplyment.objects.create(**applyment_data)
                transaction.savepoint_commit(save_id)
                eta = datetime.datetime.utcnow() + datetime.timedelta(seconds=3)
                task_id = automatic_audit_applyment.apply_async(({"applyment_id": applyment.id},), eta=eta)
                return Response({'success': '提交成功,请耐心等待客服审核生效', 'goods_id': instance.id}, status=status.HTTP_200_OK)
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                error_enum = {
                    "name": '商品名称',
                    "caption": '品牌',
                    "desc_detail": '商品介绍',
                    "market_price": '市场价',
                    "default_image": '商品封面图',
                    "manufacturer": '厂商',
                    "specifications": '规格',
                    "remain_stock": '库存',
                    "image": '商品轮播图'
                }
                for key, value in error_enum.items():
                    if key in e:
                        result = f'您输入的{value}有误，请重新输入。'
                        break
                    else:
                        result = f'提交失败,请联系管理员处理。'
                return Response({'error': result}, status=status.HTTP_400_BAD_REQUEST)

    def sweep_code_identification(self, request):
        barcode = self.request.query_params.get('barcode', None)
        business_no = self.request.query_params.get('business_no', None)
        if not all([barcode, business_no]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if not barcode:
            return Response({'error': 'barcode是空格'}, status=status.HTTP_400_BAD_REQUEST)
        if barcode == ' ':
            return Response({'error': 'barcode是空格'}, status=status.HTTP_400_BAD_REQUEST)
        url = f'https://api.jisuapi.com/barcode2/query?appkey=332d5b0000350eb8&barcode={barcode}'
        response = requests.get(url=url)
        result = response.json()
        data = {}
        data['name'] = ''
        data['default_image'] = ''
        data['price'] = ''
        data['sales'] = ''
        data['goodsimage_set'] = []
        data['desc_detail'] = [{
                    "b_title": "商品说明",
                    "arr2": []
                }]
        data['market_price'] = '0.00'
        data['manufacturer'] = ''
        data['specifications'] = ''
        data['stock'] = 0
        data['caption'] = ''
        try:
            if result['status'] != 0:
                return Response(data, status=status.HTTP_200_OK)
            result = result['result']
            pic_url = result['pic']
            if 'http' in pic_url:
                try:
                    img_id = f'youhuiquanyi/{business_no}/goods_image{"%06d" % randint(0, 999999)}.png'
                    mid_img = pic_upload(requests.get(url=pic_url).content, key=img_id)
                    data['default_image'] = f'https://circle.sutpay.cn/{img_id}'
                    data['goodsimage_set'] = [f'https://circle.sutpay.cn/{img_id}']
                    data['desc_detail'] = [{
                        "b_title": "商品说明",
                        "arr2":[{
                            "title": "",
                            "text": "",
                            "img": f'https://circle.sutpay.cn/{img_id}'
                        }]
                    }]
                except Exception as e:
                    pass
            data['name'] = result['name']
            if result['price']:
                data['price'] = result['price']
            else:
                data['price'] = '0.00'
            data['manufacturer'] = result['company']
            data['caption'] = result['brand']
            data['specifications'] = result['type']
        except:
            pass
        return Response(data, status=status.HTTP_200_OK)


class LaunchedGoodsModelViewSet(ModelViewSet):
    '''商品'''

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', 'goods__merchant__name', 'level__account', 'level__name')
    filter_class = LaunchedGoodsFilter

    def get_serializer_class(self):
        if self.action == 'list':
            return LaunchedGoodsListModelSerializer
        else:
            return LaunchedGoodsListModelSerializer

    def get_queryset(self):
        user = self.request.iser
        merchant = self.request.merchant
        queryset = LaunchedGoods.objects.filter(goods__merchant_id=merchant.id)
        goods_id = self.request.query_params.get('goods_id', None)
        if goods_id:
            goods = Goods.objects.filter(id=goods_id).first()
            if goods:
                check_query = queryset.filter(goods_id=goods_id, is_self=1)
                if not check_query:
                    launched_goods_data = {}
                    launched_goods_data['name'] = goods.name
                    launched_goods_data['caption'] = goods.caption
                    launched_goods_data['goods_id'] = goods.id
                    launched_goods_data['category_id'] = goods.category_id
                    launched_goods_data['price'] = goods.price
                    launched_goods_data['point'] = goods.point
                    launched_goods_data['stock'] = goods.stock
                    launched_goods_data['is_launched'] = 0
                    launched_goods_data['create_time'] = datetime.datetime.now()
                    launched_goods_data['is_self'] = 1
                    LaunchedGoods.objects.get_or_create(defaults=launched_goods_data, goods_id=goods.id, is_self=1)
        return queryset.order_by('-is_self', 'id')

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        stock = self.request.data.get('stock', None)
        if instance.is_self != 1:
            return Response({'error': '您无权限更改其他分店库存'}, status=status.HTTP_400_BAD_REQUEST)
        if not stock:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            stock = int(stock)
        except:
            return Response({'error': '库存参数格式有误, 请输入整数型'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                if instance.is_self == 0:
                    while True:
                        instance = LaunchedGoods.objects.get(id=instance.id)
                        goods = Goods.objects.get(id=instance.goods_id)
                        origin_remain_stock = goods.remain_stock
                        launched_origin_stock = instance.stock
                        change_stock = launched_origin_stock - stock
                        new_remain_stock = origin_remain_stock - change_stock
                        launched_result = LaunchedGoods.objects.filter(id=instance.id, stock=launched_origin_stock).update(stock=stock)
                        result = Goods.objects.filter(id=instance.goods_id, remain_stock=origin_remain_stock).update(remain_stock=new_remain_stock)
                        if result == 0:
                            continue
                        if launched_result == 0:
                            continue
                        break
                else:
                    while True:
                        instance = LaunchedGoods.objects.get(id=instance.id)
                        goods = Goods.objects.get(id=instance.goods_id)
                        origin_remain_stock = goods.remain_stock
                        origin_stock = goods.stock
                        launched_origin_stock = instance.stock
                        change_stock = launched_origin_stock - stock
                        new_remain_stock = origin_remain_stock - change_stock
                        new_stock = origin_stock - change_stock
                        launched_result = LaunchedGoods.objects.filter(id=instance.id, stock=launched_origin_stock).update(stock=stock)
                        result = Goods.objects.filter(id=instance.goods_id, remain_stock=origin_remain_stock).update(remain_stock=new_remain_stock, stock=new_stock)
                        if result == 0:
                            continue
                        if launched_result == 0:
                            continue
                        break
            except Exception as e:
                logger.error(e)
                # 事务回滚
                transaction.savepoint_rollback(save_id)
                return Response({'error': '修改失败'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
            return Response({'success': '修改成功'}, status=status.HTTP_200_OK)

    def partial_update(self, request, *args, **kwargs):
        instance = self.get_object()
        is_launched = self.request.data.get('is_launched', None)
        if instance.is_self != 1:
            return Response({'error': '您无权限更改其他分店库存'}, status=status.HTTP_400_BAD_REQUEST)
        if not is_launched:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if str(is_launched) not in ['0', '1']:
            return Response({'error': '参数有误'}, status=status.HTTP_400_BAD_REQUEST)
        if str(is_launched) == '0':
            instance.is_launched = 0
            instance.save()
            return Response({'success': '下架成功'}, status=status.HTTP_200_OK)
        else:
            instance.is_launched = 1
            instance.save()
            return Response({'success': '上架成功'}, status=status.HTTP_200_OK)


class MerchantBusinessCategoryModelViewSet(ModelViewSet):

    queryset = MerchantBusinessCategory.objects.all()
    serializer_class = MerchantBusinessCategoryModelSerializer


class MerchantBillModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('merchant__name', 'merchant__wyfMerchantID')
    filter_class = MerchantBillFilter

    def get_queryset(self):
        user = self.request.iser
        merchant = self.request.merchant
        queryset = MerchantBill.objects.filter(merchant_id=merchant.id)
        return queryset.order_by('-receipts_time', 'id')

    def get_serializer_class(self):
        if self.action == 'list':
            return MerchantBillListModelSerializer
        else:
            return MerchantBillRetrieveModelSerializer

    def export_merchant_bill(self, request):
        user = self.request.iser
        merchant = self.request.merchant
        receipts_time_end = self.request.query_params.get('receipts_time_end', None)
        receipts_time_begin = self.request.query_params.get('receipts_time_begin', None)
        settlement_time_end = self.request.query_params.get('settlement_time_end', None)
        settlement_time_begin = self.request.query_params.get('settlement_time_begin', None)
        payable_amount_min = self.request.query_params.get('payable_amount_min', None)
        payable_amount_max = self.request.query_params.get('payable_amount_max', None)
        bill_state = self.request.query_params.get('bill_state', None)
        search = self.request.query_params.get('search', None)
        bill_type = self.request.query_params.get('bill_type', None)
        condition = f'WHERE merchant_id={merchant.id}'
        if search:
            condition = condition + f' AND (merchant_id IN (SELECT id FROM tb_merchant WHERE name LIKE "%{search}%" OR short_name LIKE "%{search}%" OR wyfMerchantID LIKE "%{search}%"))'
        if bill_state:
            condition = condition + f' AND bill_state in ({bill_state})'
        if bill_type:
            condition = condition + f' AND bill_type in ({bill_type})'
        if receipts_time_begin:
            condition = condition + f' AND receipts_time >= "{receipts_time_begin + " 00:00:00"}"'
        if receipts_time_end:
            condition = condition + f' AND receipts_time <= "{receipts_time_end + " 23:59:59"}"'
        if settlement_time_begin:
            condition = condition + f' AND settlement_time >= "{settlement_time_begin + " 00:00:00"}"'
        if settlement_time_end:
            condition = condition + f' AND settlement_time <= "{settlement_time_end + " 23:59:59"}"'
        if payable_amount_min:
            condition = condition + f' AND payable_amount >= "{payable_amount_min}"'
        if payable_amount_max:
            condition = condition + f' AND payable_amount <= "{payable_amount_max}"'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        try:
            sql = f'''
            SELECT e.*,f.channel_name FROM (SELECT c.*,d.city_name,district_name,branch_name FROM (SELECT a.*,b.name,short_name,wyfMerchantID FROM (SELECT id,merchant_id,DATE_FORMAT(receipts_time,'%Y-%m-%d')AS receipts_time,DATE_FORMAT(settlement_time,'%Y-%m-%d %H:%i:%S')AS settlement_time,payable_amount,bill_state,account_bank,account_name,account_number,settlement_amount,level_id,channel_id FROM tb_merchant_bill {condition})AS a LEFT JOIN(SELECT id,name,short_name,wyfMerchantID FROM tb_merchant)AS b ON a.merchant_id=b.id)AS c LEFT JOIN (SELECT id,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id)AS e LEFT JOIN (SELECT id,name AS channel_name FROM tb_channel)AS f ON e.channel_id=f.id;
            '''
            cursor.execute(sql)
        except:
            sql = f'''
            SELECT e.*,f.channel_name FROM (SELECT c.*,d.city_name,district_name,branch_name FROM (SELECT a.*,b.name,short_name,wyfMerchantID FROM (SELECT id,merchant_id,DATE_FORMAT(receipts_time,'%Y-%m-%d')AS receipts_time,DATE_FORMAT(settlement_time,'%Y-%m-%d %H:%i:%S')AS settlement_time,payable_amount,bill_state,account_bank,account_name,account_number,settlement_amount,level_id,channel_id FROM tb_merchant_bill)AS a LEFT JOIN(SELECT id,name,short_name,wyfMerchantID FROM tb_merchant)AS b ON a.merchant_id=b.id)AS c LEFT JOIN (SELECT id,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id)AS e LEFT JOIN (SELECT id,name AS channel_name FROM tb_channel)AS f ON e.channel_id=f.id;
            '''
            cursor.execute(sql)
        ziduan = ['结算ID', '商户全称', '商户简称', '微邮付商户号', '清分日期', '结算时间', '清分金额', '结算金额',
                  '结算状态', '归属市公司', '归属区县', '归属网点', '结算通道', '结算户名', '结算卡号']
        cols = ['id', 'name', 'short_name', 'wyfMerchantID', 'receipts_time', 'settlement_time', 'payable_amount', 'settlement_amount',
                'bill_state', 'city_name', 'district_name', 'branch_name', 'channel_name', 'account_name', 'account_number']
        response = StreamingHttpResponse(self.get_merchant_bill_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('结算单信息.csv'))
        return response

    def get_merchant_bill_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        STATUS_ENUM = {
            1: '待结算',
            2: '结算中',
            3: '已结算',
            4: '已撤销',
            5: '结算失败'
        }
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col == 'bill_state':
                    tmp_str += '"%s",' % (STATUS_ENUM[row[col]])
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"


class MerchantSettlementRecordModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_class = MerchantSettlementRecordFilter
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('merchant__name', 'merchant__short_name', 'merchant__wyfMerchantID')

    def get_queryset(self):
        user = self.request.iser
        merchant = self.request.merchant
        queryset = MerchantSettlementRecord.objects.filter(merchant_id=merchant.id)
        return queryset.order_by('-settlement_time', 'id')

    def get_serializer_class(self):
        if self.action == 'list':
            return MerchantSettlementRecordListModelSerializer
        else:
            return MerchantSettlementRecordRetrieveModelSerializer

    def export_settlementrecord(self, request):
        merchant = self.request.merchant
        settlement_time_begin = self.request.query_params.get('settlement_time_begin', None)
        settlement_time_end = self.request.query_params.get('settlement_time_end', None)
        status = self.request.query_params.get('status', None)
        channel_id = self.request.query_params.get('channel_id', None)
        search = self.request.query_params.get('search', None)
        condition = f'WHERE merchant_id={merchant.id}'
        if search:
            condition = condition + f' AND (merchant_id IN (SELECT id FROM tb_merchant WHERE name LIKE "%{search}%" OR short_name LIKE "%{search}%" OR wyfMerchantID LIKE "%{search}%"))'
        if status:
            condition = condition + f' AND status in ({status})'
        if channel_id:
            condition = condition + f' AND channel_id in ({channel_id})'
        if settlement_time_begin:
            condition = condition + f' AND settlement_time >= "{settlement_time_begin + " 00:00:00"}"'
        if settlement_time_end:
            condition = condition + f' AND settlement_time <= "{settlement_time_end + " 23:59:59"}"'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        try:
            sql = f'''
            SELECT * FROM (SELECT e.*,f.channel_name FROM (SELECT c.*,d.city_name,district_name,branch_name FROM (SELECT a.*,b.merchant_name,short_name,wyfMerchantID FROM (SELECT id,account_name,account_number,status,amount,DATE_FORMAT(settlement_time,'%Y-%m-%d %H:%i:%S')AS settlement_time,fail_reason,merchant_id,channel_id,level_id FROM tb_merchant_settlement_record {condition})AS a LEFT JOIN (SELECT id,name AS merchant_name,short_name,wyfMerchantID FROM tb_merchant)AS b ON a.merchant_id=b.id)AS c LEFT JOIN (SELECT id,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id)AS e LEFT JOIN (SELECT id,name AS channel_name FROM tb_channel)AS f ON e.channel_id=f.id)AS j LEFT JOIN (SELECT settlement_record_id,GROUP_CONCAT(payable_amount)AS payable_amount,GROUP_CONCAT(DATE_FORMAT(receipts_time,'%Y-%m-%d'))AS receipts_time FROM (SELECT g.bill_id,settlement_record_id,h.payable_amount,receipts_time FROM (SELECT bill_id,settlement_record_id FROM tb_merchant_bill_settlement_record)AS g LEFT JOIN (SELECT id,receipts_time,payable_amount FROM tb_merchant_bill)AS h ON g.bill_id=h.id)AS i GROUP BY settlement_record_id)AS k ON j.id=k.settlement_record_id;
            '''
            cursor.execute(sql)
        except:
            sql = f'''
            SELECT * FROM (SELECT e.*,f.channel_name FROM (SELECT c.*,d.city_name,district_name,branch_name FROM (SELECT a.*,b.merchant_name,short_name,wyfMerchantID FROM (SELECT id,account_name,account_number,status,amount,DATE_FORMAT(settlement_time,'%Y-%m-%d %H:%i:%S')AS settlement_time,fail_reason,merchant_id,channel_id,level_id FROM tb_merchant_settlement_record)AS a LEFT JOIN (SELECT id,name AS merchant_name,short_name,wyfMerchantID FROM tb_merchant)AS b ON a.merchant_id=b.id)AS c LEFT JOIN (SELECT id,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id)AS e LEFT JOIN (SELECT id,name AS channel_name FROM tb_channel)AS f ON e.channel_id=f.id)AS j LEFT JOIN (SELECT settlement_record_id,GROUP_CONCAT(payable_amount)AS payable_amount,GROUP_CONCAT(DATE_FORMAT(receipts_time,'%Y-%m-%d'))AS receipts_time FROM (SELECT g.bill_id,settlement_record_id,h.payable_amount,receipts_time FROM (SELECT bill_id,settlement_record_id FROM tb_merchant_bill_settlement_record)AS g LEFT JOIN (SELECT id,receipts_time,payable_amount FROM tb_merchant_bill)AS h ON g.bill_id=h.id)AS i GROUP BY settlement_record_id)AS k ON j.id=k.settlement_record_id;
            '''
            cursor.execute(sql)
        ziduan = ['结算ID', '商户全称', '商户简称', '微邮付商户号', '清分日期', '结算时间', '清分金额', '结算金额',
                  '结算状态', '结算失败原因', '归属市公司', '归属区县', '归属网点', '结算通道', '结算户名', '结算卡号']
        cols = ['id', 'merchant_name', 'short_name', 'wyfMerchantID', 'receipts_time', 'settlement_time', 'payable_amount', 'amount',
                'status', 'fail_reason', 'city_name', 'district_name', 'branch_name', 'channel_name', 'account_name', 'account_number']
        response = StreamingHttpResponse(self.get_settlementrecord_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('结算单信息.csv'))
        return response

    def get_settlementrecord_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        STATUS_ENUM = {
            1: '待结算',
            2: '结算中',
            3: '已结算',
            4: '已撤销',
            5: '结算失败'
        }
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col == 'status':
                    tmp_str += '"%s",' % (STATUS_ENUM[row[col]])
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"


class MerchantMonthlyBillModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    filter_class = MerchantMonthlyBillFilter
    search_fields = ('merchant__name', 'merchant__wyfMerchantID')

    def get_queryset(self):
        user = self.request.iser
        merchant = self.request.merchant
        receipts_time_begin = self.request.query_params.get('receipts_time_begin', None)
        receipts_time_end = self.request.query_params.get('receipts_time_end', None)
        try:
            if '_mutable' in self.request.query_params.__dict__:
                self.request.query_params.__dict__['_mutable'] = True
        except:
            pass
        if receipts_time_begin:
            try:
                datetime.datetime.strptime(receipts_time_begin, '%Y-%m')
            except:
                raise serializers.ValidationError({'error': '时间格式有误'})
            self.request.query_params['receipts_time_begin'] = f'{receipts_time_begin}-01'
        if receipts_time_end:
            try:
                datetime.datetime.strptime(receipts_time_end, '%Y-%m')
            except:
                raise serializers.ValidationError({'error': '时间格式有误'})
            self.request.query_params['receipts_time_end'] = f'{receipts_time_end}-01'
        queryset = MerchantMonthlyBill.objects.filter(merchant_id=merchant.id)
        return queryset.order_by('-receipts_time', '-id')

    def get_serializer_class(self):
        if self.action == 'list':
            return MerchantMonthlyBillListModelSerializer
        else:
            return MerchantMonthlyBillRetrieveModelSerializer


class AfterSaleApplicationFormModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    filter_class = AfterSaleApplicationFormFilter
    search_fields = ('order__merchant__name', 'order__merchant__wyfMerchantID')

    def get_queryset(self):
        user = self.request.iser
        merchant = self.request.merchant
        queryset = AfterSaleApplicationForm.objects.filter(order__merchant_id=merchant.id).exclude(form_status=4)
        return queryset.order_by('-id')

    def get_serializer_class(self):
        if self.action == 'list':
            return AfterSaleApplicationFormListModelSerializer
        else:
            return AfterSaleApplicationFormRetrieveModelSerializer

    def update(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        if instance.form_status not in [1, 8]:
            return Response({'error': '申请单状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        audit_status = self.request.data.get('audit_status', None)
        return_msg = self.request.data.get('return_msg', None)
        order = instance.order
        if order.state != 5:
            return Response({'error': '订单状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        if not audit_status:
            return Response({'error': '请上传审核参数'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.form_status == 8:
            if instance.reason_type == 1:
                if str(audit_status) == '2':
                    url = 'https://api.gdwxyf.com/api/refund.do'
                    datetime_now = datetime.datetime.now()
                    order_id = f'{datetime_now.strftime("%Y%m%d%H%M%S")}{"%06d" % randint(0, 999999)}'
                    body = {
                        "program_id": "202316837141378884",
                        "shop_id": order.merchant.ruiyinxinMerchantID,
                        "refund_order_id": order_id,
                        "order_id": order.orderNum
                    }
                    key = '6715C7D4435343BA0459EAEC2334D81B'
                    sign = get_sign(body, key)
                    body['sign'] = sign
                    response = requests.post(url=url, json=body)
                    result = response.json()
                    if result['result_code'] == 'success':
                        refund_order_data = {}
                        refund_order_data['order_id'] = order.id
                        refund_order_data['merchantuser_id'] = user.id
                        refund_order_data['operator_role'] = 4
                        refund_order_data['refund_order_id'] = order_id
                        refund_order_data['refund_transaction_id'] = result['refund_transaction_id']
                        refund_order_data['plat_refund_order_id'] = result['plat_refund_order_id']
                        refund_order_data['refund_money'] = result['refund_money']
                        refund_order_data['refund_procedure_money'] = result['commission']
                        refund_order_data['refund_time'] = datetime.datetime.strptime(result['refund_end_time'], '%Y%m%d%H%M%S')
                        refund_order_data['remark'] = '商户同意退款'
                        RefundOrderInfo.objects.create(**refund_order_data)
                        order.state = 8
                        # order.refund_money += Decimal(result['refund_money'])
                        order.refund_money = order.realpay_amount
                        order.out_refund_no = order_id
                        order.refund_id = result['refund_transaction_id']
                        order.save()
                        instance.form_status = 2
                        # instance.refund_money = result['refund_money']
                        instance.refund_time = datetime.datetime.strptime(result['refund_end_time'], '%Y%m%d%H%M%S')
                        instance.save()
                        return Response({'success': '退款成功'}, status=status.HTTP_200_OK)
                    else:
                        refund_order_data = {}
                        refund_order_data['refund_status'] = 2
                        refund_order_data['operator_role'] = 4
                        refund_order_data['order_id'] = order.id
                        refund_order_data['merchantuser_id'] = user.id
                        refund_order_data['return_msg'] = result['error_msg']
                        refund_order_data['refund_order_id'] = order_id
                        refund_order_data['refund_time'] = datetime_now
                        refund_order_data['remark'] = '商户同意退款'
                        RefundOrderInfo.objects.create(**refund_order_data)
                        instance.form_status = 3
                        instance.return_msg = result['error_msg']
                        instance.save()
                        return Response({'error': f'退款失败,原因:{result["error_msg"]}'}, status=status.HTTP_400_BAD_REQUEST)
                else:
                    if not return_msg:
                        return Response({'error': '请写明拒绝退款原因'}, status=status.HTTP_400_BAD_REQUEST)
                    order.state = instance.order_status
                    order.save()
                    instance.form_status = 11
                    instance.return_msg = return_msg
                    instance.save()
                    OrderAdvance.objects.create(
                        order_id=instance.order_id,
                        status=7,
                        remark='商户驳回申请',
                        merchantuser_id=user.id
                    )
                    return Response({'success': '操作成功'}, status=status.HTTP_200_OK)
            else:
                if str(audit_status) == '2':
                    expired_time = datetime.datetime.now() + datetime.timedelta(days=3)
                    instance.form_status = 5
                    instance.expired_time = expired_time
                    instance.save()
                    return Response({'success': '操作成功'}, status=status.HTTP_200_OK)
                else:
                    if not return_msg:
                        return Response({'error': '请写明拒绝退款原因'}, status=status.HTTP_400_BAD_REQUEST)
                    order.state = instance.order_status
                    order.save()
                    instance.form_status = 11
                    instance.return_msg = return_msg
                    instance.save()
                    OrderAdvance.objects.create(
                        order_id=instance.order_id,
                        status=7,
                        remark='商户驳回申请',
                        merchantuser_id=user.id
                    )
                    return Response({'success': '操作成功'}, status=status.HTTP_200_OK)
        else:
            if str(audit_status) == '2':
                url = 'https://api.gdwxyf.com/api/refund.do'
                datetime_now = datetime.datetime.now()
                order_id = f'{datetime_now.strftime("%Y%m%d%H%M%S")}{"%06d" % randint(0, 999999)}'
                body = {
                    "program_id": "202316837141378884",
                    "shop_id": order.merchant.ruiyinxinMerchantID,
                    "refund_order_id": order_id,
                    "order_id": order.orderNum
                }
                key = '6715C7D4435343BA0459EAEC2334D81B'
                sign = get_sign(body, key)
                body['sign'] = sign
                response = requests.post(url=url, json=body)
                result = response.json()
                if result['result_code'] == 'success':
                    refund_order_data = {}
                    refund_order_data['order_id'] = order.id
                    refund_order_data['merchantuser_id'] = user.id
                    refund_order_data['operator_role'] = 4
                    refund_order_data['refund_order_id'] = order_id
                    refund_order_data['refund_transaction_id'] = result['refund_transaction_id']
                    refund_order_data['plat_refund_order_id'] = result['plat_refund_order_id']
                    refund_order_data['refund_money'] = result['refund_money']
                    refund_order_data['refund_procedure_money'] = result['commission']
                    refund_order_data['refund_time'] = datetime.datetime.strptime(result['refund_end_time'],
                                                                                  '%Y%m%d%H%M%S')
                    refund_order_data['remark'] = '商户同意退款'
                    RefundOrderInfo.objects.create(**refund_order_data)
                    order.state = 8
                    # order.refund_money += Decimal(result['refund_money'])
                    order.refund_money = order.realpay_amount
                    order.out_refund_no = order_id
                    order.refund_id = result['refund_transaction_id']
                    order.save()
                    instance.form_status = 2
                    # instance.refund_money = result['refund_money']
                    instance.refund_time = datetime.datetime.strptime(result['refund_end_time'], '%Y%m%d%H%M%S')
                    instance.save()
                    return Response({'success': '退款成功'}, status=status.HTTP_200_OK)
                else:
                    refund_order_data = {}
                    refund_order_data['refund_status'] = 2
                    refund_order_data['operator_role'] = 4
                    refund_order_data['order_id'] = order.id
                    refund_order_data['merchantuser_id'] = user.id
                    refund_order_data['return_msg'] = result['error_msg']
                    refund_order_data['refund_order_id'] = order_id
                    refund_order_data['refund_time'] = datetime_now
                    refund_order_data['remark'] = '商户同意退款'
                    RefundOrderInfo.objects.create(**refund_order_data)
                    instance.form_status = 3
                    instance.return_msg = result['error_msg']
                    instance.save()
                    return Response({'error': f'退款失败,原因:{result["error_msg"]}'}, status=status.HTTP_400_BAD_REQUEST)
            else:
                if not return_msg:
                    return Response({'error': '请写明拒绝退款原因'}, status=status.HTTP_400_BAD_REQUEST)
                order.state = instance.order_status
                order.save()
                instance.form_status = 11
                instance.return_msg = return_msg
                instance.save()
                OrderAdvance.objects.create(
                    order_id=instance.order_id,
                    status=7,
                    remark='商户驳回申请',
                    merchantuser_id=user.id
                )
                return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def receive_goods(self, request):
        user = self.request.iser
        form_id = self.request.data.get('form_id', None)
        if not form_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=form_id)
        except:
            return Response({'error': '无效订单id'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.form_status != 9:
            return Response({'error': '申请单状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.reason_type == 2:
            instance.form_status = 1
            instance.save()
        else:
            instance.form_status = 7
            instance.save()
        OrderAdvance.objects.create(
            order_id=instance.order_id,
            status=4,
            remark='商户确认收货',
            merchantuser_id=user.id
        )
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def deliver_goods(self, request):
        user = self.request.iser
        express_array = self.request.data.get('express_array', None)
        form_id = self.request.data.get('form_id', None)
        if not all([express_array, form_id]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=form_id)
        except:
            return Response({'error': '无效申请单id'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.form_status != 7:
            return Response({'error': '申请单状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        order = instance.order
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                for express in express_array:
                    try:
                        ExpressType.objects.get(id=express['express_type_id'])
                    except:
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': '无效快递类型'}, status=status.HTTP_400_BAD_REQUEST)
                    express_data = {}
                    express_data['express_type_id'] = express['express_type_id']
                    express_data['express_number'] = express['express_number']
                    express, create = Express.objects.get_or_create(defaults=express_data, express_number=express['express_number'])
                    relevance_data = {}
                    relevance_data['order_id'] = order.id
                    relevance_data['express_id'] = express.id
                    ExpressOrderRelevance.objects.get_or_create(defaults=relevance_data, order_id=relevance_data['order_id'], express_id=relevance_data['express_id'])
                instance.form_status = 10
                instance.save()
                OrderAdvance.objects.create(
                    order_id=order.id,
                    status=3,
                    remark='商家重新发货',
                    merchantuser_id=user.id
                )
                # try:
                #     express_send.delay({'id': instance.id, 'express_id': express.id})
                # except:
                #     pass
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                return Response({'error': '操作失败'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
            return Response({'success': '操作成功'}, status=status.HTTP_200_OK)


class GoodsCommentModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('merchant__name', 'goods__name')
    filter_class = OrderGoodsFilter
    serializer_class = GoodsCommentModelSerializer

    def get_queryset(self):
        user = self.request.iser
        merchant = self.request.merchant
        queryset = OrderGoods.objects.filter(is_commented=1, order__merchant_id=merchant.id).order_by('-id')
        return queryset

